package cn.edu.tju.core.security.service;

import cn.edu.tju.core.model.Authority;
import cn.edu.tju.core.model.User;
import cn.edu.tju.core.security.SecurityUtils;
import cn.edu.tju.core.security.repository.UserRepository;
import cn.edu.tju.core.security.rest.dto.RegisterDTO;
import cn.edu.tju.elm.exception.UnauthorizedException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

@Service
@Transactional
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;

    @Transactional(readOnly = true)
    public User getUserWithAuthorities() {
        return SecurityUtils.getCurrentUsername()
                .flatMap(userRepository::findOneWithAuthoritiesByUsername)
                .orElseThrow(() -> new UnauthorizedException("未登录"));
    }

    @Transactional(readOnly = true)
    public Optional<User> findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Transactional(readOnly = true)
    public boolean existsByUsername(String username) {
        return userRepository.findByUsername(username).isPresent();
    }

    public User registerUser(RegisterDTO registerDTO) {
        if (existsByUsername(registerDTO.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }

        Set<Authority> authorities = new HashSet<>();
        authorities.add(Authority.USER());
        if (registerDTO.getType() == 0) { // 商家
            authorities.add(Authority.BUSINESS());
        }

        LocalDateTime now = LocalDateTime.now();
        User newUser = User.builder()
                .username(registerDTO.getUsername())
                .password(SecurityUtils.BCryptPasswordEncode(registerDTO.getPassword()))
                .activated(true)
                .authorities(authorities)
                .createTime(now)
                .updateTime(now)
                .deleted(false)
                .build();

        return userRepository.save(newUser);
    }

    public User updatePassword(String username, String newPassword) {
        User user = userRepository.findOneWithAuthoritiesByUsername(username)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));

        user.setPassword(SecurityUtils.BCryptPasswordEncode(newPassword));
        user.setUpdateTime(LocalDateTime.now());

        return userRepository.save(user);
    }

    public User updateUser(User user) {
        user.setUpdateTime(LocalDateTime.now());
        return userRepository.save(user);
    }

    @Transactional(readOnly = true)
    public Boolean isEmptyUserTable() {
        return userRepository.count() == 0;
    }
}